import * as signalR from "@microsoft/signalr";
const { VITE_GLOBAL_API_URL } = import.meta.env;
import { getToken } from "@/utils/auth";
import { useUserStoreHook } from "@/store/modules/user";

// SignalR 配置信息
const signalRConfig: { hubUrl: string; accessTokenFactory: () => string } = {
  hubUrl: `${VITE_GLOBAL_API_URL}signalRHub`,
  accessTokenFactory: () => getToken().accessToken
};

let hubConnection: signalR.HubConnection | null = null;

// 创建 SignalR 连接
const createSignalRConnection = (config: {
  hubUrl: string;
  accessTokenFactory: () => string;
}): signalR.HubConnection => {
  const connection: signalR.HubConnection = new signalR.HubConnectionBuilder()
    .withUrl(config.hubUrl, {
      accessTokenFactory: config.accessTokenFactory
    })
    .withAutomaticReconnect()
    //.configureLogging(signalR.LogLevel.Information)
    .build();

  // 设置重连事件监听器
  connection.onreconnecting(error => {
    console.log("SignalR Hub reconnecting:", error);
  });

  // 设置重连成功事件监听器
  connection.onreconnected(connectionId => {
    console.log("SignalR Hub reconnected. New connectionId:", connectionId);
  });

  // 设置连接关闭事件监听器
  connection.onclose(error => {
    console.log("SignalR Hub connection closed:", error);
  });

  return connection;
};

// 启动 SignalR 连接
const startSignalRConnection = async (): Promise<void> => {
  if (
    !hubConnection ||
    hubConnection.state !== signalR.HubConnectionState.Connected
  ) {
    try {
      hubConnection = createSignalRConnection(signalRConfig);
      await hubConnection.start();
      console.log("SignalR Hub connected.");
    } catch (error) {
      console.error(`SignalR Hub connection error: ${error}`);
    }
  }
};

// 订阅消息
const subscribeToReceiveMessage = async (
  methodName: string,
  callback: (...args: any[]) => void
): Promise<void> => {
  await startSignalRConnection();
  if (hubConnection) {
    hubConnection.on(methodName, (...args: any[]) => {
      if (callback) {
        callback(...args);
      }
    });
  }
};

// 发送消息
const sendMessage = async (
  methodName: string,
  ...args: any[]
): Promise<void> => {
  await startSignalRConnection();
  if (hubConnection) {
    try {
      await hubConnection.invoke(methodName, ...args);
    } catch (error) {
      console.error(`Error sending message: ${error}`);
    }
  }
};

// 取消订阅
const unsubscribeFromMessage = async (
  methodName: string,
  callback: (...args: any[]) => void
): Promise<void> => {
  await startSignalRConnection();
  if (hubConnection) {
    hubConnection.off(methodName, callback);
  }
};

// 主动断开连接
const disconnectSignalR = async (): Promise<void> => {
  await startSignalRConnection();
  if (hubConnection) {
    try {
      await hubConnection.stop();
      console.log("SignalR Hub disconnected.");
    } catch (error) {
      console.error(`SignalR Hub disconnection error: ${error}`);
    }
  }
};

// 消息模板类
class MessageTemplate {
  private static _idCounter: number = 0;

  private _id: number;
  private _content: string;
  private _username: string = useUserStoreHook().username;
  private _messageType: MessageType = MessageType.UpdateUserStatus;

  constructor(content: string, messageType: MessageType) {
    // 自动分配模板 ID
    this._id = ++MessageTemplate._idCounter;
    this._content = content;
    this._messageType = messageType; // 将新消息类型赋值给属性
    this._username = useUserStoreHook().username;
  }

  // 获取消息模板 ID
  get id(): number {
    return this._id;
  }

  // 设置用户名
  set id(id: number) {
    this._id = id;
  }

  // 获取消息模板内容
  get content(): string {
    return this._content;
  }

  // 设置消息模板内容
  set content(content: string) {
    this._content = content;
  }

  // 获取用户名
  get username(): string {
    return this._username;
  }

  // 设置用户名
  set username(name: string) {
    this._username = name;
  }

  // 获取消息类型
  get messageType(): MessageType {
    return this._messageType;
  }

  // 设置消息类型
  set messageType(type: MessageType) {
    this._messageType = type;
  }

  toString(): string {
    return JSON.stringify({
      id: this._id,
      content: this._content,
      username: this._username,
      messageType: MessageType[this._messageType] // 将消息类型转换为枚举名称
    });
  }
}

// 其他可能需要的方法，例如验证模板内容等

enum MessageType {
  Online,
  Offline,
  UpdateUserStatus,
  UpdataUserAvatar,
  UpdateUserRole,
  UpdateRoleStatus,
  ForceLogout,
  UpdateMenu,
  UpdateRoleMenu,
  DeleteRole,
  DeleteMenu
}

const getMessageType = (typeString: string): MessageType | undefined => {
  switch (typeString) {
    case "UpdateUserStatus":
      return MessageType.UpdateUserStatus;
    case "UpdataUserAvatar":
      return MessageType.UpdataUserAvatar;
    case "UpdateUserRole":
      return MessageType.UpdateUserRole;
    case "Online":
      return MessageType.Online;
    case "Offline":
      return MessageType.Offline;
    case "UpdateRoleStatus":
      return MessageType.UpdateRoleStatus;
    case "ForceLogout":
      return MessageType.ForceLogout;
    case "UpdateMenu":
      return MessageType.UpdateMenu;
    case "UpdateRoleMenu":
      return MessageType.UpdateRoleMenu;
    case "DeleteRole":
      return MessageType.DeleteRole;
    case "DeleteMenu":
      return MessageType.DeleteMenu;
    default:
      return undefined; // 或者抛出一个错误，视情况而定
  }
};

export {
  startSignalRConnection,
  subscribeToReceiveMessage,
  sendMessage,
  unsubscribeFromMessage,
  disconnectSignalR,
  MessageTemplate,
  MessageType,
  getMessageType
};
